<?php
/**
 * 模板处理
 * @copyright 2020-2021 WillPHP
 * @author NoMind<24203741@qq.com/113344.com>
 * @version WillPHPv3
 * @since 2021-12-16
 */
namespace wiphp;
defined('WIPHP_URI') or die('Access Denied');
class Template {
	public static function render($viewfile, $vars = []) {
		$shtml_open = Config::get('app.shtml_open');
		$vhash = App::getViewHash();		
		$vars['vhash'] = $vhash;		
		if (!$shtml_open || basename($viewfile) == 'jump.html') {
			self::parseTemplate($viewfile, $vars);		
		} else {	
			$sfile = PATH_SHTML.'/'.$vhash.'.shtml';
			$shtml_time = Config::get('app.shtml_time');			
			$ftimeok = true;
			if ($shtml_time > 0) {
				$ntime = time();
				$ftime = file_exists($sfile)? filemtime($sfile) : 0;
				$ftimeok = $ftime > ($ntime - $shtml_time);
			}
			if (is_file($sfile) && $ftimeok) {
				include $sfile;
			} else {
				ob_start();
				self::parseTemplate($viewfile, $vars);		
				$content = ob_get_contents();
				file_put_contents($sfile, $content);
				self::shtmlToHtml($content); //生成html
			}
		}
	}
	//生成html
	private static function shtmlToHtml($content) {
		$shtml_html = Config::get('app.shtml_html');
		if ($shtml_html) {
			$route = strtolower(__MODULE__.'/'.__ACTION__);
			$params = input();
			$hfile = url($route, $params);
			$hfile = str_replace(__URL__, '', $hfile);
			if ($hfile == '/') {
				$hfile = '/index'.URL_SUFFIX;
			}
			//生成路径
			$hfile = WIPHP_URI.'/public/static'.$hfile;
			//处理内容
			$root = __ROOT__.'/';
			$content = str_replace('href="'.$root.'static/', 'href="', $content);
			$content = str_replace('src="'.$root.'static/', 'src="', $content);
			$content = str_replace('href="'.$root, 'href="', $content);
			$content = str_replace('index.php/', '', $content);
			$fn = config('app.html_replace');
			if (!empty($fn) && function_exists($fn)) {
				$content = $fn($content);
			}
			//生成html
			file_put_contents($hfile, $content);			
		}
	}	
	protected static function parseTemplate($viewfile, $vars = []) {
		if (basename($viewfile) == 'jump.html') {
			$viewc_file = PATH_VIEWC.'/view-jump.html.php';
		} else {
			$viewc_file = PATH_VIEWC.'/view-'.strtolower(__MODULE__).'_'.basename($viewfile).'.php';
		}
		if (!file_exists($viewc_file) || filemtime($viewc_file) < filemtime($viewfile)) {
			$content = file_get_contents($viewfile);
			$content = self::compile($content, $vars);
			file_put_contents($viewc_file, $content);
		}
		if (isset($vars['viewc_file'])) unset($vars['viewc_file']);
		extract($vars);
		include $viewc_file;
	}
	
	protected static function compile($html, $vars = []) {
		$vk = '([a-zA-Z0-9_\x7f-\xff]*)'; //匹配键名
		$vv = '([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)'; //匹配变量
		$html = preg_replace_callback('/\{\s*include\s+[\"\']?(.+?)[\"\']?\s*\}/i',function ($match) {
			return file_get_contents(THEME_PATH.'/'.$match[1]);
		}, $html);
		if (preg_match('/\{\s*include\s+[\"\']?(.+?)[\"\']?\s*\}/i', $html)) {
			$html = preg_replace_callback('/\{\s*include\s+[\"\']?(.+?)[\"\']?\s*\}/i',function ($match) {
				return file_get_contents(THEME_PATH.'/'.$match[1]);
			}, $html);
		}
		$pattern = [
				'/__(\w+)__/i',
				'/\{\s*\$'.$vv.'\s*\}/i',
				'/\{\s*\$'.$vv.'\.'.$vk.'\s*\}/i',
				'/\{\s*\$'.$vv.'\[[\'"]?'.$vk.'[\'"]?\]\s*\}/i',
				'/\{\s*if\s*(.+?)\s*\}/i',
				'/\{\s*\/(foreach|if)\s*\}/i',
				'/\{\s*(else if|elseif)\s*(.+?)\s*\}/i',
				'/\{\s*else\s*\}/i',
				'/\{\s*foreach\s+\$'.$vv.'\s+as\s+\$'.$vv.'\s*\}/i',
				'/\{\s*foreach\s+\$'.$vv.'\s+as\s+\$'.$vv.'\s*=>\s*\$'.$vv.'\s*\}/i',
				'/\{\s*empty\s+\$'.$vv.'\s*\}/i',
				'/\{\s*:'.$vv.'\((.*?)\)\s*\}/i',
				'/\{\s*:'.$vv.'\((.*?)\)\->'.$vv.'\((.*?)\)\s*\}/i',
				'/\{\s*var\s+\$'.$vv.'\s*=\s*(.+?)\s*\}/i',
				'/\{\s*\$'.$vv.'\|'.$vv.'\s*\}/i',
				'/\{\s*\$'.$vv.'\.'.$vv.'\|'.$vv.'\s*\}/i',
				'/\{\s*\$'.$vv.'\[[\'"]'.$vv.'[\'"]\]\|'.$vv.'\s*\}/i',
				'/\{\s*\$'.$vv.'\|'.$vv.'=(.+?)\s*\}/i',
				'/\{\s*\$'.$vv.'\.'.$vv.'\|'.$vv.'=(.+?)\s*\}/i',
				'/\{\s*\$'.$vv.'\[[\'"]'.$vv.'[\'"]\]\|'.$vv.'=(.+?)\s*\}/i',
				'/\{\s*\$'.$vv.'\.'.$vk.'\.'.$vk.'\s*\}/i',
				'/\{\s*\$'.$vv.'\[[\'"]?'.$vk.'[\'"]?\]'.'\[[\'"]?'.$vk.'[\'"]?\]\s*\}/i',
		];
		$replacement = [
				'<?php echo __\\1__; ?>',
				'<?php echo $\\1; ?>',
				'<?php echo $\\1[\'\\2\']; ?>',
				'<?php echo $\\1[\'\\2\']; ?>',
				'<?php if (\\1) {?>',
				'<?php }?>',
				'<?php }elseif (\\2) {?>',
				'<?php }else {?>',
				'<?php foreach((array)$\\1 as $\\2) { ?>',
				'<?php foreach((array)$\\1 as $\\2 => $\\3) { ?>',
				'<?php } if (empty($\\1)) { ?>',
				'<?php echo \\1(\\2); ?>',
				'<?php echo \\1(\\2)->\\3(\\4); ?>',
				'<?php $\\1 = \\2; ?>',
				'<?php echo \\2($\\1); ?>',
				'<?php echo \\3($\\1[\'\\2\']); ?>',
				'<?php echo \\3($\\1[\'\\2\']); ?>',
				'<?php echo \\2($\\1,\\3); ?>',
				'<?php echo \\3($\\1[\'\\2\'],\\4); ?>',
				'<?php echo \\3($\\1[\'\\2\'],\\4); ?>',
				'<?php echo $\\1[\'\\2\'][\'\\3\']; ?>',
				'<?php echo $\\1[\'\\2\'][\'\\3\']; ?>',
		];
		$html = preg_replace($pattern, $replacement, $html);		
		return $html;
	}
}